📊 Gráficos Interactivos y Visualizaciones con Plotly¶
Programación Avanzada (comisión 1) - Ciencia de Datos, Universidad Nacional de Guillermo Brown (UNAB)
Autores: Tomas Muino, Ivana Noelia Zurdo, Sebastian Sanchez Bentolila, Uriel Capdevila
Fecha: 09 de junio de 2025

Temario
- ¿Que es Plotly?
- Gráficos 2D
- Gráficos 3D
- Subplots
- Personalización Avanzada de Gráficos (Graph Objects)
- Modelado de Clases
- Exportación de gráficos
- Recursos adicionales
Introducción: Dando Vida a tus Datos con Plotly¶
En el mundo actual, la cantidad de datos que generamos y analizamos es inmensa. Para entender patrones, tendencias e insights ocultos en esta montaña de información, la visualización de datos se vuelve una herramienta indispensable. Pero, ¿qué pasa si queremos ir más allá de las imágenes estáticas? Aquí es donde entra Plotly.

¿Qué es Plotly?¶
Plotly es una biblioteca de código abierto diseñada para crear gráficos interactivos y visualizaciones web. Es extremadamente versátil, compatible con múltiples lenguajes de programación (Python, R, Julia, MATLAB, JavaScript) y está construida sobre las robustas tecnologías web D3.js, HTML y CSS. Esto significa que los gráficos que crees con Plotly no solo son estéticos, sino que también son dinámicos y pueden ser fácilmente compartidos en la web.
¿Por qué la Interactividad es Crucial?¶
La interactividad en las visualizaciones no es solo un lujo, es una necesidad:
- Exploración Dinámica: Permite a los usuarios hacer zoom, pan, seleccionar regiones y pasar el ratón (hover) sobre los datos para obtener detalles, fomentando un análisis más profundo.
- Descubrimiento de Insights: Al poder manipular el gráfico, se pueden descubrir patrones que quizás no serían evidentes en una imagen estática.
- Comunicación Efectiva: Facilita la adaptación de la presentación de los datos a diferentes preguntas o audiencias, mejorando la comprensión.
- Engagement del Usuario: Las visualizaciones interactivas son más atractivas y mantienen al usuario comprometido con el análisis.
¿Por qué elegir Plotly?¶
- Interactividad Nativa: Zoom, pan, hover, selección de puntos, etc., vienen de fábrica.
- Amplia Gama de Gráficos: Soporta desde los gráficos más comunes (barras, líneas, dispersión) hasta los más complejos (3D, geoespaciales, financieros, estadísticos).
- Estilo Profesional y Personalización: Ofrece un control granular sobre cada aspecto visual del gráfico.
- Integración Sencilla: Funciona perfectamente en Jupyter Notebooks, aplicaciones web (con Dash), y se puede exportar a HTML.
- Rendimiento: Optimizado para manejar grandes conjuntos de datos.
Instalación¶
Si aún no las tienes, puedes instalarlas usando pip:
pip install plotly
# Comenzemos importando las librerias necesarias
import plotly.express as px
import plotly.graph_objects as go
import numpy as np
import pandas as pd
Gráficos en 2D¶
En el análisis de datos, los gráficos 2D (bidimensionales) son representaciones visuales que permiten explorar la relación entre dos variables, facilitando la interpretación y comunicación de los datos. Estos gráficos se construyen en un plano cartesiano, utilizando un eje X (horizontal) y un eje Y (vertical), lo cual los hace ideales para estudiar distribuciones, tendencias, correlaciones y patrones.
Los gráficos 2D son fundamentales en la etapa de visualización exploratoria, ya que nos permiten:
- Identificar posibles relaciones entre variables.
- Detectar valores atípicos o comportamientos inusuales.
- Comparar diferentes grupos o categorías.
- Comprender la distribución de los datos
Gráfico de Línea¶
El gráfico de líneas es un tipo de gráfico 2D que se utiliza principalmente para visualizar la evolución de una variable a lo largo del tiempo o para mostrar una tendencia continua. Se representa uniendo puntos con líneas rectas, donde cada punto corresponde a un par ordenado (X, Y).
- El eje X suele representar una variable temporal (como días, meses, años, etc.) o una secuencia ordenada.
- El eje Y representa los valores correspondientes de la variable de interés.
Este tipo de gráfico es muy útil cuando se quiere:
- Observar tendencias o patrones temporales.
- Comparar la evolución de múltiples series de datos.
- Detectar aumentos, caídas o estacionalidades en una variable.
Son especialmente útiles en análisis financiero, métricas de rendimiento, series temporales y monitoreo de variables en el tiempo.
# Datos simulados de precios de acciones
dates = pd.to_datetime(pd.date_range(start='2023-01-01', periods=100, freq='D'))
price_a = np.random.randn(100).cumsum() + 50
price_b = np.random.randn(100).cumsum() + 60
df_stocks = pd.DataFrame({
'Fecha': dates,
'Acción A': price_a,
'Acción B': price_b
})
fig_line = px.line(df_stocks,
x="Fecha",
y=["Acción A", "Acción B"], # Múltiples líneas
title="Evolución del Precio de Acciones Simuladas")
fig_line.update_layout(xaxis_title="Fecha",
yaxis_title="Precio ($)")
fig_line.show()
C:\Users\sebas\anaconda3\Lib\site-packages\_plotly_utils\basevalidators.py:106: FutureWarning: The behavior of DatetimeProperties.to_pydatetime is deprecated, in a future version this will return a Series containing python datetime objects instead of an ndarray. To retain the old behavior, call `np.array` on the result v = v.dt.to_pydatetime()
Gráfico de Dispersión (Scatter Plot)¶
El gráfico de dispersión es una visualización 2D que permite representar la relación entre dos variables cuantitativas. Cada punto en el gráfico corresponde a una observación en el conjunto de datos, y su posición está determinada por sus valores en los ejes X e Y.
Este tipo de gráfico es especialmente útil para:
- Explorar la correlación entre dos variables.
- Identificar agrupamientos o patrones.
- Detectar valores atípicos o casos fuera de lo común.
- Observar relaciones lineales o no lineales.
# Cargamos el famoso dataset 'iris'
df_iris = px.data.iris()
print("Primeras 5 filas del dataset Iris:")
print(df_iris.head())
fig_scatter = px.scatter(df_iris,
x="sepal_width",
y="sepal_length",
color="species", # Colorea los puntos según la especie
size='petal_length', # El tamaño del punto según la longitud del pétalo
hover_data=['petal_width'], # Información adicional al pasar el mouse
title="Relación Ancho vs. Largo del Sépalo por Especie")
# Añadimos interactividad de ejes y nombres más claros
fig_scatter.update_layout(xaxis_title="Ancho del Sépalo (cm)",
yaxis_title="Largo del Sépalo (cm)")
fig_scatter.show()
Primeras 5 filas del dataset Iris: sepal_length sepal_width petal_length petal_width species species_id 0 5.1 3.5 1.4 0.2 setosa 1 1 4.9 3.0 1.4 0.2 setosa 1 2 4.7 3.2 1.3 0.2 setosa 1 3 4.6 3.1 1.5 0.2 setosa 1 4 5.0 3.6 1.4 0.2 setosa 1
Gráfico de Barras¶
El gráfico de barras es utilizada para representar y comparar cantidades entre diferentes categorías. En este gráfico, cada categoría se representa con una barra cuya longitud (o altura) es proporcional a su valor.
- El eje X suele representar las categorías (por ejemplo, países, productos, clases, etc.).
- El eje Y muestra la magnitud asociada a cada categoría (frecuencia, conteo, porcentaje, etc.).
Este tipo de gráfico es muy útil para:
- Comparar valores entre distintos grupos o categorías.
- Visualizar la distribución de frecuencias de una variable cualitativa.
- Detectar qué categorías tienen valores más altos o más bajos.
Los gráficos de barras pueden ser:
- Verticales (barras hacia arriba) o horizontales (barras hacia los costados).
- Simples, cuando muestran una sola variable.
- Agrupados o apilados, para comparar varias series en cada categoría.
# Cargamos el dataset 'tips' (propinas)
df_tips = px.data.tips()
print("\nPrimeras 5 filas del dataset Tips:")
print(df_tips.head())
# Agrupamos los datos para obtener la cuenta total promedio por día de la semana
daily_bill_avg = df_tips.groupby('day')['total_bill'].mean().reset_index()
fig_bar = px.bar(daily_bill_avg,
x="day",
y="total_bill",
color="day", # Colorea las barras por día
title="Promedio de la Cuenta Total por Día de la Semana")
fig_bar.update_layout(xaxis_title="Día de la Semana",
yaxis_title="Promedio de Cuenta Total ($)")
fig_bar.show()
Primeras 5 filas del dataset Tips: total_bill tip sex smoker day time size 0 16.99 1.01 Female No Sun Dinner 2 1 10.34 1.66 Male No Sun Dinner 3 2 21.01 3.50 Male No Sun Dinner 3 3 23.68 3.31 Male No Sun Dinner 2 4 24.59 3.61 Female No Sun Dinner 4
Gráfico de Pastel (Pie Chart)¶
El gráfico de pastel es una visualización 2D que se utiliza para mostrar la proporción relativa de cada categoría respecto a un total. Representa los datos como sectores circulares (rebanadas) dentro de un círculo completo, donde cada sector indica el porcentaje de una categoría específica.
Este tipo de gráfico es útil cuando se desea:
- Visualizar cómo se divide un total entre varias categorías.
- Mostrar la proporción relativa de cada componente.
- Comunicar porcentajes de forma simple e intuitiva.
Aspectos importantes:
- Cada sector del gráfico representa una categoría, y su ángulo es proporcional a su valor.
- Todos los sectores deben sumar 100%.
- Son más efectivos cuando se tienen pocas categorías (3 a 6) con diferencias claras entre ellas.
# Reutilizamos el dataset tips
# Contar la cantidad de transacciones por día
daily_counts = df_tips['day'].value_counts().reset_index()
daily_counts.columns = ['day', 'count']
fig_pie = px.pie(daily_counts,
values='count',
names='day',
title='Distribución de Transacciones por Día de la Semana',
hover_data=['count'],
labels={'count':'Número de Transacciones'})
fig_pie.update_traces(textposition='inside', textinfo='percent+label') # Muestra porcentaje y etiqueta dentro
fig_pie.show()
Gráfico de Caja y Bigote (Boxplot)¶
El gráfico de caja y bigote, conocido como boxplot, es una herramienta estadística que permite visualizar la distribución de una variable numérica, resumiendo sus principales características en cinco valores: mínimo, primer cuartil (Q1), mediana (Q2), tercer cuartil (Q3) y máximo.
Este tipo de gráfico es especialmente útil para:
- Observar la dispersión y la asimetría de los datos.
- Comparar la distribución de una variable entre diferentes grupos.
- Detectar valores atípicos (outliers).
- Identificar la mediana y los rangos intercuartílicos.
Estructura del gráfico:
- La caja representa el rango intercuartílico (Q1 a Q3), es decir, el 50% central de los datos.
- La línea dentro de la caja indica la mediana (Q2).
- Los bigotes se extienden hasta los valores mínimo y máximo que no se consideran outliers.
- Los puntos fuera de los bigotes se interpretan como valores atípicos.
Este gráfico es particularmente útil cuando se trabaja con conjuntos de datos grandes o cuando se desea comparar varias distribuciones al mismo tiempo, por ejemplo, mediante múltiples boxplots en paralelo.
fig_box = px.box(df_iris,
x="species",
y="sepal_length",
color="species",
title="Distribución del Largo del Sépalo por Especie")
fig_box.update_layout(xaxis_title="Especie", yaxis_title="Largo del Sépalo (cm)")
fig_box.show()
Gráfico de Violín¶
El gráfico de violín es una visualización que combina las características del boxplot y del gráfico de densidad, permitiendo analizar tanto la distribución estadística como la forma de los datos en una sola figura.
Es especialmente útil para:
- Comparar la distribución de una variable numérica entre diferentes grupos.
- Observar la forma de la distribución (simetría, multimodalidad, concentración de valores).
- Identificar la mediana, los cuartiles y los valores extremos.
Estructura del gráfico:
- Contiene una curva de densidad suavizada en ambos lados, que muestra cómo se distribuyen los datos.
- En el centro, puede incluir un boxplot con la mediana y los cuartiles.
- La anchura del gráfico en cada punto indica la frecuencia relativa de los datos en esa región.
El gráfico de violín es particularmente útil cuando se desea:
- Ver más detalles que en un boxplot clásico, especialmente en distribuciones no normales o multimodales.
- Comparar distribuciones entre múltiples categorías de manera visualmente clara y compacta.
fig_violin = px.violin(df_iris,
y="sepal_length",
x="species",
color="species",
box=True, # Muestra un box plot dentro del violin
points="all", # Muestra todos los puntos individuales
title="Densidad y Distribución del Largo del Sépalo por Especie")
fig_violin.update_layout(xaxis_title="Especie", yaxis_title="Largo del Sépalo (cm)")
fig_violin.show()
Histogramas¶
El histograma es un tipo de gráfico 2D que se utiliza para representar la distribución de frecuencia de una variable numérica continua. Divide el rango de los datos en intervalos (bins) y cuenta cuántos valores caen dentro de cada uno de ellos.
Cada barra del histograma:
- Representa un intervalo de valores (también llamado clase).
- Tiene una altura proporcional a la frecuencia o densidad de observaciones dentro de ese intervalo.
Este gráfico es especialmente útil para:
- Analizar la forma de la distribución de una variable (simetría, sesgo, curtosis).
- Detectar modas (picos de frecuencia) y distribuciones multimodales.
- Identificar posibles valores atípicos o extremos.
- Observar la dispersión y el rango de los datos.
Aspectos clave:
- La elección del número de intervalos (bins) influye en la apariencia del histograma. Pocos bins pueden ocultar detalles, mientras que demasiados pueden generar ruido.
- A diferencia del gráfico de barras, que se utiliza para variables categóricas, el histograma se aplica a variables numéricas continuas.
# Crear datos ficticios: 500 edades entre 18 y 70 años
np.random.seed(42)
edades = np.random.normal(loc=35, scale=10, size=500) # media = 35, desviación = 10
edades = np.clip(edades, 18, 70) # Limitar valores entre 18 y 70
df = pd.DataFrame({"Edad": edades})
# Crear histograma con Plotly
fig = px.histogram(
df,
x="Edad",
nbins=20,
title="Distribución de Edades",
labels={"Edad": "Edad de personas"},
color_discrete_sequence=["mediumseagreen"]
)
# Opciones de visualización
fig.update_layout(
bargap=0.1,
xaxis_title="Edad",
yaxis_title="Cantidad de personas",
template="simple_white"
)
fig.show()
Gráficos en 3D¶
Los gráficos 3D (tridimensionales) son representaciones visuales que permiten mostrar relaciones entre tres variables simultáneamente, agregando una tercera dimensión al plano tradicional 2D. Se construyen en un espacio cartesiano con tres ejes:
- Eje X (horizontal)
- Eje Y (vertical)
- Eje Z (profundidad)
Estos gráficos son especialmente útiles cuando se desea:
- Visualizar cómo varía una variable dependiente en función de dos variables independientes.
- Analizar superficies, volúmenes o distribuciones en un espacio tridimensional.
- Detectar patrones complejos, agrupamientos o relaciones no evidentes en 2D.
La visualización 3D puede ser particularmente potente cuando se combina con interactividad, permitiendo al usuario rotar, hacer zoom y explorar los datos desde diferentes ángulos.
Gráfico de superficie¶
El gráfico de superficie es una visualización tridimensional que representa una superficie continua definida por tres variables: dos variables independientes (ejes X e Y) y una variable dependiente (eje Z). Este gráfico muestra cómo varía una variable en función de dos dimensiones simultáneamente.
Es especialmente útil para:
- Visualizar funciones matemáticas o modelos con dos variables independientes.
- Explorar la forma y características de una superficie o terreno.
- Detectar máximos, mínimos, mesetas, valles y otros patrones en datos espaciales o multivariados.
- Analizar la interacción entre dos variables y su efecto en una tercera.
Características principales:
- La superficie se construye conectando puntos en una malla (grid) de coordenadas (X, Y, Z).
- Puede incluir variaciones de color para representar intensidades o valores adicionales.
- La interactividad permite rotar, hacer zoom y explorar la superficie desde diferentes ángulos.
Este tipo de gráfico es muy utilizado en análisis científico, ingeniería, geografía, economía, y en cualquier área donde se modelen fenómenos en tres dimensiones.
# Read data from a csv
z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv')
fig = go.Figure(data=[go.Surface(z=z_data.values)])
fig.update_layout(title=dict(text='Mt Bruno Elevation'), autosize=False,
width=500, height=500,
margin=dict(l=65, r=50, b=65, t=90))
fig.show()
Gráficos de dispersión 3D (3D scatter plots)¶
El gráfico de dispersión 3D es una extensión del scatter plot tradicional que permite representar tres variables cuantitativas en un solo gráfico, utilizando un espacio tridimensional. Cada punto en el gráfico se define por un trío de coordenadas (X, Y, Z), lo que permite explorar relaciones más complejas entre los datos.
Este tipo de visualización es útil para:
- Analizar cómo se relacionan tres variables simultáneamente.
- Identificar grupos, tendencias o patrones en un espacio tridimensional.
- Detectar valores atípicos en un entorno más complejo que el plano 2D.
Características clave:
- El eje X, eje Y y eje Z representan cada una de las tres variables.
- Opcionalmente, se pueden utilizar colores o tamaños de los puntos para incluir una cuarta variable.
- Los puntos pueden girarse e inspeccionarse desde diferentes ángulos si se habilita la interactividad.
fig_scatter_3d = px.scatter_3d(df_iris,
x='sepal_width',
y='sepal_length',
z='petal_width',
color='species',
title="Dispersión 3D de Iris por Dimensiones Florales")
fig_scatter_3d.update_layout(scene = dict(
xaxis_title='Ancho Sépalo',
yaxis_title='Largo Sépalo',
zaxis_title='Ancho Pétalo'
))
fig_scatter_3d.show()
Gráficos de Malla y Rejilla (Mesh y Wireframe Plots)¶
Los gráficos de malla y rejilla son visualizaciones tridimensionales que representan una superficie a través de una estructura formada por líneas que conectan puntos de datos en un espacio 3D.
Gráfico de malla (mesh plot): Muestra una superficie compuesta por polígonos (generalmente triángulos o cuadriláteros) que conectan los puntos de datos, rellenando el área entre ellos y creando una forma continua.
Gráfico de rejilla (wireframe plot): Representa la misma estructura de superficie, pero sólo con las líneas que forman la malla, sin relleno. Esto permite ver claramente la geometría y la forma de la superficie sin distracciones visuales.
Estos gráficos son útiles para:
- Visualizar la topología y forma de superficies complejas.
- Analizar relaciones entre dos variables independientes y una variable dependiente.
- Entender la estructura de datos espaciales o funciones matemáticas en tres dimensiones.
- Facilitar la interpretación de superficies cuando el relleno completo puede ocultar detalles.
Características clave:
- Se construyen a partir de una malla de puntos (X, Y) con valores Z asociados.
- Permiten rotar y explorar la superficie en 3D para observarla desde distintos ángulos.
- En gráficos de malla, el color o la transparencia pueden usarse para mejorar la percepción visual.
Estos gráficos son muy usados en ingeniería, física, geografía, y cualquier disciplina que requiera modelar y analizar superficies tridimensionales.
import plotly.graph_objects as go
fig = go.Figure(data=[
go.Mesh3d(
x=[0, 1, 2, 0],
y=[0, 0, 1, 2],
z=[0, 2, 0, 1],
colorbar=dict(title=dict(text='z')),
colorscale=[[0, 'gold'],
[0.5, 'mediumturquoise'],
[1, 'magenta']],
# Intensity of each vertex, which will be interpolated and color-coded
intensity=[0, 0.33, 0.66, 1],
# i, j and k give the vertices of triangles
# here we represent the 4 triangles of the tetrahedron surface
i=[0, 0, 0, 1],
j=[1, 2, 3, 2],
k=[2, 3, 1, 3],
name='y',
showscale=True
)
])
fig.show()
Subplots: Múltiples gráficos en una misma figura¶
En análisis de datos, muchas veces es útil mostrar varios gráficos juntos en una misma figura para comparar visualmente diferentes aspectos o variables. Esto se logra mediante subplots, es decir, gráficos organizados en una cuadrícula dentro de una misma visualización.
¿Qué son los Subplots?¶
Un subplot es un gráfico individual contenido dentro de una figura más grande. Utilizar subplots permite:
- Comparar diferentes tipos de gráficos (líneas, barras, dispersión, etc.).
- Mostrar visualizaciones relacionadas sin separarlas en distintas figuras.
- Mejorar la organización y legibilidad del análisis.
¿Cómo crear subplots en Plotly?¶
Plotly ofrece la función make_subplots() desde el módulo plotly.subplots, que permite organizar múltiples gráficos en filas y columnas dentro de una figura.
from plotly.subplots import make_subplots
# Crear una figura con 1 fila y 2 columnas
fig_subplots = make_subplots(rows=1, cols=2,
subplot_titles=("Gráfico de Barras por Sexo", "Gráfico de Dispersión por Día"))
# Gráfico de barras para la primera columna
df_sex_avg = df_tips.groupby('sex')['total_bill'].mean().reset_index()
fig_subplots.add_trace(
go.Bar(x=df_sex_avg['sex'], y=df_sex_avg['total_bill'], name='Promedio por Sexo', marker_color=['skyblue', 'salmon']),
row=1, col=1
)
# Gráfico de dispersión para la segunda columna
fig_subplots.add_trace(
go.Scatter(x=df_tips['total_bill'], y=df_tips['tip'], mode='markers', name='Propina vs. Cuenta',
marker=dict(color=df_tips['size'], showscale=True, colorscale='Viridis',
colorbar=dict(title='Tamaño Grupo'))),
row=1, col=2
)
# Actualizar el layout de los subplots
fig_subplots.update_layout(title_text="Ejemplo de Subplots con Plotly",
height=500, showlegend=False) # Quitar la leyenda general
fig_subplots.update_xaxes(title_text="Sexo", row=1, col=1)
fig_subplots.update_yaxes(title_text="Promedio Cuenta (<span class='math-inline'>)", row=1, col=1)
fig_subplots.update_xaxes(title_text="Cuenta Total (</span>)", row=1, col=2)
fig_subplots.update_yaxes(title_text="Propina ($)", row=1, col=2)
fig_subplots.show()
Personalización Avanzada de Gráficos (Graph Objects)¶
Plotly no solo permite crear visualizaciones interactivas de forma sencilla, sino que también ofrece un alto grado de personalización. Esto permite controlar cada aspecto del gráfico: desde colores y estilos de líneas hasta anotaciones, formas, fuentes, cuadrículas y más.
En este ejemplo, se muestra cómo:
- Crear una figura vacía (
go.Figure()). - Agregar múltiples trazas (
go.Scatter) con estilos personalizados. - Configurar el layout: títulos, ejes, fondo, leyendas, cuadrículas.
- Añadir formas y anotaciones para destacar elementos importantes.
Elementos personalizados del gráfico¶
Trazas: Se añaden dos series (
Serie SenoidalySerie Cosinusoidal) con diferentes estilos:- Colores personalizados (
blue,red). - Modos combinados de visualización (
markers+lines,lines). - Estilo de línea (continua, punteada).
- Tamaño y símbolo de los marcadores.
- Colores personalizados (
Layout:
- Título del gráfico y de los ejes.
- Fondo del área de trazado (
plot_bgcolor) y fondo general del gráfico (paper_bgcolor). - Estilo de fuente (familia, tamaño, color).
- Color de la cuadrícula en ambos ejes.
- Leyenda personalizada con título.
- Modo de interacción
hovermode='x unified', que muestra los valores de todas las series en un mismo punto sobre el eje X.
Formas:
- Se agrega una línea horizontal con estilo punteado (
dashdot) en y = 0 para resaltar una referencia importante.
- Se agrega una línea horizontal con estilo punteado (
Anotaciones:
- Se agrega un texto con flecha en un punto específico del gráfico (
x=5, y=0.5), destacando un "Punto de interés".
- Se agrega un texto con flecha en un punto específico del gráfico (
Ventajas de esta personalización¶
- Mejora la legibilidad y estética de los gráficos.
- Permite destacar información clave.
- Facilita la comunicación efectiva de los resultados del análisis.
- Hace que las visualizaciones sean más profesionales e interactivas.
Este nivel de control convierte a plotly.graph_objects en una herramienta ideal para presentaciones, dashboards, y cuadernos técnicos donde se requiere precisión visual y claridad en los datos mostrados.
# Datos simulados
x_data = np.linspace(0, 10, 50)
y_data_1 = np.sin(x_data) + np.random.randn(50) * 0.1
y_data_2 = np.cos(x_data) + np.random.randn(50) * 0.1
# 1. Crear una figura vacía
fig_go = go.Figure()
# 2. Añadir la primera traza (Scatter)
fig_go.add_trace(go.Scatter(
x=x_data,
y=y_data_1,
mode='markers+lines', # Puntos y líneas
name='Serie Senoidal',
marker=dict(color='blue', size=8, symbol='circle'),
line=dict(width=2, dash='solid')
))
# 3. Añadir una segunda traza (Scatter con otro estilo)
fig_go.add_trace(go.Scatter(
x=x_data,
y=y_data_2,
mode='lines',
name='Serie Cosinusoidal',
line=dict(color='red', width=1, dash='dot') # Línea punteada
))
# 4. Configurar el layout (título, ejes, leyenda, etc.)
fig_go.update_layout(
title='Comparación de Series Senoidal y Cosinusoidal (Graph Objects)',
xaxis_title='Eje X',
yaxis_title='Eje Y',
legend_title='Series',
hovermode='x unified', # Muestra un tooltip unificado para todas las trazas en un punto X
plot_bgcolor='white', # Fondo del área de trazado
paper_bgcolor='lightgray', # Fondo de toda la figura
font=dict(family="Arial", size=12, color="#333"),
xaxis=dict(gridcolor='lightgrey'), # Color de la cuadrícula
yaxis=dict(gridcolor='lightgrey')
)
# 5. Añadir formas y anotaciones
# Una línea horizontal
fig_go.add_shape(type="line",
x0=0, y0=0, x1=10, y1=0,
line=dict(color="green", width=2, dash="dashdot"))
# Una anotación
fig_go.add_annotation(x=5, y=0.5,
text="Punto de interés",
showarrow=True,
arrowhead=1,
font=dict(size=10, color="purple"))
fig_go.show()
Modelado en Clases: Programación Orientada a Objetos para Visualizaciones¶
¿Qué es la Programación Orientada a Objetos (POO)?¶
La Programación Orientada a Objetos (POO) es un paradigma de programación que se basa en el concepto de "objetos", que representan entidades del mundo real con características (atributos) y comportamientos (métodos). Este enfoque permite organizar el código de forma más modular, reutilizable y escalable.
En la POO, un objeto es una instancia de una clase, que actúa como un molde o plantilla. Cada clase define atributos y métodos que caracterizan a los objetos de ese tipo.
Beneficios de la POO¶
- Favorece la reutilización de código mediante herencia.
- Facilita la organización y mantenimiento del software.
- Permite crear sistemas más flexibles y escalables.
- Promueve el uso de abstracción, ocultando detalles innecesarios al usuario final.
Pilares Fundamentales de la POO¶
La POO se basa en cuatro pilares principales:
1. Abstracción¶
La abstracción consiste en modelar objetos del mundo real seleccionando solo los atributos y comportamientos relevantes para el problema que se quiere resolver. Se enfoca en lo esencial, ocultando los detalles innecesarios.
Ejemplo: En un sistema bancario, una clase
CuentaBancariapuede abstraer los atributossaldo,titulary los métodosdepositar()yretirar().
2. Encapsulamiento¶
El encapsulamiento es el principio que permite ocultar la implementación interna de un objeto y proteger sus datos, exponiendo solo lo necesario mediante interfaces públicas. Se logra controlando el acceso a los atributos a través de métodos (getters y setters).
Esto evita modificaciones accidentales y mantiene la integridad de los datos.
3. Herencia¶
La herencia permite crear nuevas clases a partir de otras existentes, reutilizando y extendiendo su comportamiento. La clase original se llama clase padre o superclase, y la nueva clase se llama clase hija o subclase.
Esto favorece la reutilización del código y la creación de jerarquías lógicas.
4. Polimorfismo¶
El polimorfismo permite que diferentes objetos respondan al mismo mensaje (método) de manera distinta según su clase. Esto se logra mediante sobrecarga de métodos o redefinición en clases derivadas.
Permite utilizar una misma interfaz para interactuar con objetos de distintas clases de forma flexible.
@startuml
class DatasetAnalyzer {
- ruta_csv: str
- df: DataFrame
- metricas: GeneradorMetricas
- visualizador: VisualizadorPlotly
- reporte_html: str
+ __init__(ruta_csv: str)
+ cargar_datos(): None
+ validar_datos(): None
+ obtener_info_columnas(): list
+ generar_reporte(): None
+ exportar_reporte(nombre: str): None
}
class GeneradorMetricas {
- df: DataFrame
+ __init__(df: DataFrame)
+ resumen_estadistico(): DataFrame
+ contar_nulos(): Series
+ tipos_de_datos(): Series
+ correlaciones(): DataFrame
}
class VisualizadorPlotly {
- df: DataFrame
+ __init__(df: DataFrame)
+ graficar_dispersion(x: str, y: str, color: str = None): None
+ graficar_barras(x: str, y: str = None): None
+ graficar_linea(x: str, y: str): None
+ graficar_pastel(columna: str): None
+ graficar_box(x: str = None, y: str = None): None
+ graficar_violin(x: str = None, y: str = None): None
+ graficar_histograma(columna: str): None
+ graficar_3D(x: str, y: str, z: str): None
}
DatasetAnalyzer --> GeneradorMetricas
DatasetAnalyzer --> VisualizadorPlotly
@enduml
import os
import datetime
class GeneradorMetricas:
def __init__(self, df):
self.df = df
def resumen_estadistico(self):
return self.df.describe(include='all').transpose()
def contar_nulos(self):
return self.df.isnull().sum()
def tipos_de_datos(self):
return self.df.dtypes
def correlaciones(self):
num_df = self.df.select_dtypes(include=np.number)
return num_df.corr(numeric_only=True)
class VisualizadorPlotly:
def __init__(self, df):
self.df = df
def graficar_dispersion(self, x, y, color=None):
fig = px.scatter(self.df, x=x, y=y, color=color, title=f"Dispersión: {x} vs {y}")
fig.show()
def graficar_barras(self, x, y=None):
if y:
fig = px.bar(self.df, x=x, y=y, title=f"Barras: {x} vs {y}")
else:
fig = px.bar(self.df[x].value_counts().reset_index(), x='index', y=x, title=f"Conteo de {x}")
fig.show()
def graficar_linea(self, x, y):
fig = px.line(self.df, x=x, y=y, title=f"Gráfico de línea: {x} vs {y}")
fig.show()
def graficar_pastel(self, columna):
fig = px.pie(self.df, names=columna, title=f"Gráfico de pastel: {columna}")
fig.show()
def graficar_box(self, x=None, y=None):
fig = px.box(self.df, x=x, y=y, title="Box Plot")
fig.show()
def graficar_violin(self, x=None, y=None):
fig = px.violin(self.df, x=x, y=y, box=True, points='all', title="Gráfico Violin")
fig.show()
def graficar_histograma(self, columna):
fig = px.histogram(self.df, x=columna, title=f"Histograma de {columna}")
fig.show()
def graficar_3D(self, x, y, z):
fig = px.scatter_3d(self.df, x=x, y=y, z=z, title=f"Gráfico 3D: {x}, {y}, {z}")
fig.show()
class DatasetAnalyzer:
def __init__(self, ruta_csv):
self.ruta_csv = ruta_csv
self.df = None
self.metricas = None
self.visualizador = None
self.reporte_html = ""
def cargar_datos(self):
try:
self.df = pd.read_csv(self.ruta_csv)
self.metricas = GeneradorMetricas(self.df)
self.visualizador = VisualizadorPlotly(self.df)
print(f"✅ Dataset cargado correctamente con {self.df.shape[0]} filas y {self.df.shape[1]} columnas.")
except Exception as e:
print(f"❌ Error al cargar el dataset: {e}")
def validar_datos(self):
print("\n🔍 Validación del Dataset:")
print("- Tipos de Datos:\n", self.metricas.tipos_de_datos())
print("\n- Cantidad de Nulos:\n", self.metricas.contar_nulos())
def obtener_info_columnas(self):
return self.df.columns.tolist()
def generar_reporte(self):
print("\n📊 Resumen Estadístico:")
display(self.metricas.resumen_estadistico())
print("\n📈 Correlaciones:")
display(self.metricas.correlaciones())
print("\n📋 Primeras filas del dataset:")
display(self.df.head())
def exportar_reporte():
pass
# Cargar el analizador
df_covid = DatasetAnalyzer("Datasets/casos_covid19_2020.csv")
df_covid.cargar_datos()
# Validar datos
df_covid.validar_datos()
C:\Users\sebas\AppData\Local\Temp\ipykernel_7088\2886629009.py:72: DtypeWarning: Columns (10,11,13) have mixed types. Specify dtype option on import or set low_memory=False.
✅ Dataset cargado correctamente con 573332 filas y 14 columnas. 🔍 Validación del Dataset: - Tipos de Datos: numero_de_caso int64 fecha_apertura_snvs object fecha_toma_muestra object fecha_clasificacion object provincia object barrio object comuna float64 genero object edad float64 clasificacion object fecha_fallecimiento object fallecido object fecha_alta object tipo_contagio object dtype: object - Cantidad de Nulos: numero_de_caso 0 fecha_apertura_snvs 0 fecha_toma_muestra 139 fecha_clasificacion 0 provincia 2607 barrio 307062 comuna 307062 genero 31 edad 449 clasificacion 0 fecha_fallecimiento 563559 fallecido 563559 fecha_alta 508115 tipo_contagio 297429 dtype: int64
# Visualizaciones
df_covid.visualizador.graficar_histograma(columna='edad')
df_covid.visualizador.graficar_pastel(columna='genero')
df_covid.visualizador.graficar_dispersion(x='comuna', y='edad', color='genero')
df_covid.visualizador.graficar_box(x='tipo_contagio', y='edad')
Exportación de gráficos¶
Plotly permite no solo crear visualizaciones interactivas, sino también exportarlas para su uso en presentaciones, informes o publicaciones. Existen dos formas principales de exportar un gráfico:
1. Exportar como archivo HTML¶
La opción más simple y poderosa es exportar el gráfico como un archivo .html. Este formato conserva toda la interactividad del gráfico, permitiendo su uso en navegadores sin necesidad de depender de Jupyter.
fig.write_html("grafico_interactivo.html")
2. Exportar como imagen (PNG, JPEG, PDF, SVG)¶
Necesitás tener kaleido instalado en Python.
fig.write_image("grafico.png")
Tengamos en cuenta que al guardarlo con uno formato estático no convervara su interactividad
3. Captura manual¶
Si todo falla, podés usar la opción de descargar que aparece en el gráfico cuando lo abrís en el visor interactivo, o simplemente capturar la pantalla.
# Exportar como archivo HTML interactivo el mapa de personalización avanzada
try:
fig_go.write_html("Exportaciones/grafico_interactivo.html")
fig_subplots.write_html("Exportaciones/sub_plots.html")
print("Guardado con exito")
except:
print("Error al guardar")
Guardado con exito
Requerimientos¶
Para este Jupyter Notebook se han utiizado las siguientes librerias con sus versiones.
txt
dash==3.0.4
plotly==6.1.2
numpy==1.26.4
pandas==2.1.4
Para la presentación interactiva se ha utilizado RISE en su siguiente versión rise==5.7.1.
Siguiendo los pasos, en el cuaderno se abrió la metada Edit ---> Edit Notebook Metadata y se le agrego Rise (se tendría que ver algo así).
{
"celltoolbar": "Slideshow",
"colab": {
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3 (ipykernel)",
"language": "python"
},
"language_info": {
"name": "python",
"version": "3.11.7",
"mimetype": "text/x-python",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"pygments_lexer": "ipython3",
"nbconvert_exporter": "python",
"file_extension": ".py"
},
"rise": {
"scroll": true
}
}
Luego, se activo View --> Cell Toolbar --> SlideShow y se ha clasificado cada bloque en 4 categorias Slide,Sub-slide, Fragment, Skip y Notes.
Ya con las celdas modificadas, exportamos el trabajo File --> Download as --> Reveal.js slides (.slides.html).
Por útlimo, ya con el html generado, lo abrimos en VS Code, con el comando Ctrl + F buscamos la función function setScrollingSlide() . Una vez localidado, buscamos la variable var scroll = false, lo cambiamos a var scroll = true, guardamos el archivo y volvemos a refrescar la pestaña.

